package cz.data.gateway.model.utils;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;

public class RouteConstant {
    public static final List<FactoryOptions> PREDICATE_FACTORY = new ArrayList<>();
    public static final List<FactoryOptions> FILTER_FACTORY = new ArrayList<>();

    static {
        for (PredicateFactoryName value : PredicateFactoryName.values()) {
            FactoryOptions options = new FactoryOptions();
            options.setName(value.name);
            options.setValue(value.value);
            options.setArgsNames(value.argsNames);
            PREDICATE_FACTORY.add(options);
        }
        for (FilterFactoryName value : FilterFactoryName.values()) {
            FactoryOptions options = new FactoryOptions();
            options.setName(value.name);
            options.setValue(value.value);
            options.setArgsNames(value.argsNames);
            FILTER_FACTORY.add(options);
        }
    }

    @Getter
    public enum PredicateFactoryName {
        //路径断言, prefix为前缀路径
        Path("路径匹配", "Path", new Parameter("匹配规则", "patterns")),
        //请求参数断言,name为包含请求参数名称, regexp为正则匹配
        Query("请求参数", "Query", new Parameter("参数名称", "param")),
        //请求方法断言, methods为请求方法数组
        Method("请求方法", "Method", new Parameter("请求方式", "methods")),
        //主机名称断言, patterns为正则匹配名称
        Host("主机名称", "Host", new Parameter("匹配正则", "patterns")),
        //头部参数断言,name为包含头部参数名称, regexp为正则匹配
        Header("请求头参数", "Header", new Parameter("参数名称", "param")),
        //请求远程地址断言,source为地址名称
        RemoteAddr("请求远程地址", "RemoteAddr", new Parameter("远程地址", "sources")),
        //前置时间断言, datetime指定请求在此时间之前
        Before("前置时间", "Before", new Parameter("时间", "datetime")),
        //后置时间断言, datetime指定请求在此时间之后
        After("后置时间", "After", new Parameter("时间", "datetime")),
        //区间范围时间断言, datetime1为开始时间, datetime2为结束时间
        Between("区间范围时间", "Between",
                new Parameter("开始时间", "datetime1"),
                new Parameter("结束时间", "datetime2")),
        //Cookie参数断言, name为包含Cookie名称, regexp为正则匹配
        Cookie("Cookie参数", "Cookie", new Parameter("参数名称", "param"));

        private final String name;
        private final String value;
        private final Parameter[] argsNames;

        PredicateFactoryName(String name, String value, Parameter... argsNames) {
            this.name = name;
            this.value = value;
            this.argsNames = argsNames;
        }
    }

    @Getter
    public enum FilterFactoryName {
        StripPrefix("去除前缀", "StripPrefix", new Parameter("前缀部分数", "parts")),
        RewritePath("路径重写", "RewritePath",
                new Parameter("匹配正则", "regexp"),
                new Parameter("替换正则", "replacement")),
        AddRequestHeader("添加请求头参数", "AddRequestHeader",
                new Parameter("请求头参数名称", "name"),
                new Parameter("请求头参数值", "value")),
        RemoveRequestHeader ("删除请求头参数", "RemoveRequestHeader ",
                new Parameter("请求头参数名称", "name")),
        RedirectTo("重定向", "RedirectTo",
                new Parameter("状态码", "status"),
                new Parameter("重定向路径", "url")),
        SetStatus("设置响应状态码", "SetStatus", new Parameter("状态码", "status"))
        ;
        private final String name;
        private final String value;
        private final Parameter[] argsNames;

        FilterFactoryName(String name, String value, Parameter... argsNames) {
            this.name = name;
            this.value = value;
            this.argsNames = argsNames;
        }
    }

    @Getter
    @AllArgsConstructor
    public static class Parameter {

        private String name;
        private String value;
    }

    @Getter
    @Setter
    public static class FactoryOptions {
        private String name;
        private String value;
        private Parameter[] argsNames;
    }
}
